package com.sy.simpleegg.http;

import android.text.TextUtils;
import android.util.Log;

import com.sy.simpleegg.BuildConfig;
import com.sy.simpleegg.http.callback.UploadLogCallback;
import com.sy.simpleegg.http.callback.VerifyQrCodeCallback;
import com.sy.simpleegg.util.FileUtil;
import com.sy.logger.Logger;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import javax.net.ssl.HostnameVerifier;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.ConnectionPool;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;

public class HttpUtil {

    private static String TAG = "HttpUtil";

    public static void uploadFile(File file, String devNumber, UploadLogCallback uploadLogCallback) {
        try {
            OkHttpClient okHttpClient = new OkHttpClient();
            // 构建 multipart 数据
            // 数据有两个部分，一个是 a:b 的参数，和一个 txt 文件
            MultipartBody multipartBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("businessValue", "device_log_data")
                    .addFormDataPart("file", file.getName(), RequestBody.create(file, MediaType.parse("Multipart/form-data")))
                    .build();
            // 构建 request 请求
            Request request = new Request.Builder()
                    .post(multipartBody)
                    .url(BuildConfig.WHM_MQTT_HEX_AUTH_HOST + "/upload/File/iot/byBusinessValue")
                    .build();
            Call call = okHttpClient.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    try {
                        Log.d("okHttp上传失败", e.getMessage());
                        Logger.d("上传日志失败：" + e.getMessage());

                        if (uploadLogCallback != null){
                            uploadLogCallback.onFail(call, e);
                        }
                    }catch (Exception e1){
                        e1.printStackTrace();
                    }
                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    try {
                        String JSONStr = response.body().string();
                        Log.d("okHttp", JSONStr);
                        Logger.d("上传日志完成：" + JSONStr);
                        FileUtil.INSTANCE.delete(file.getAbsolutePath());
                        if (uploadLogCallback != null){
                            uploadLogCallback.onResp(call, response);
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            });
        }catch (Exception e){
            e.printStackTrace();
            Logger.d("上传日志异常：" + e.getMessage());
        }

    }

    public static void verifyQrCode(String qrCode, VerifyQrCodeCallback verifyQrCodeCallback) {
        try {
            OkHttpClient okHttpClient = new OkHttpClient();
            // 构建 multipart 数据
            // 数据有两个部分，一个是 a:b 的参数，和一个 txt 文件
//            RequestBody body = RequestBody.create(json, MediaType.parse("application/json"));
//            String json = "{\"qrcode\":\"" + qrCode +"\"}";
            String json = qrCode;
            RequestBody body = RequestBody.create(json, MediaType.parse("text/plain"));
            // 构建 request 请求
            Request request = new Request.Builder()
                    .put(body)
                    .url(BuildConfig.HOST_VERIFY_QRCODE + "/api/other/questionnaire/qrcode/" + qrCode)
                    .build();
            Call call = okHttpClient.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    try {
                        Log.d("校验二维码失败", e.getMessage());
                        Logger.d("校验二维码失败：" + e.getMessage());

                        if (verifyQrCodeCallback != null){
                            verifyQrCodeCallback.onFail(call, e);
                        }
                    }catch (Exception e1){
                        e1.printStackTrace();
                    }
                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    try {
//                        String JSONStr = response.body().string();
//                        Log.d("okHttp", JSONStr);
//                        Logger.d("校验二维码完成：" + JSONStr);
                        if (verifyQrCodeCallback != null){
                            verifyQrCodeCallback.onResp(call, response);
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            });
        }catch (Exception e){
            e.printStackTrace();
            Logger.d("校验二维码异常：" + e.getMessage());
        }

    }

    public static void getSignal(Callback callback) {
        String signalUrl = "http://192.168.1.1/api/v1/module/status";
//        OkHttpClient okHttpClient = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(signalUrl)
                .get()//默认就是GET请求，可以不写
                .build();
//        Call call = okHttpClient.newCall(request);
//        call.enqueue(callback);

        getClient().newCall(request).enqueue(callback);
    }


    /**
     * 切换网络 0-CMCC（移动） 1-CUCC（联通） 2-CTCC（电信）
     */
    public static void switchingNetwork(int netType, Callback callback) {
        String net = "CMCC";
        switch (netType) {
            case 0:
                break;
            case 1:
                net = "CUCC";
                break;
            case 2:
                net = "CTCC";
                break;
            default:
                break;
        }

        String info = "{\"searchMode\":\"3\", \"prioOperator\":\"" + net + "\", \"thresholdTmp\":\"10\", }";

        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        String postUrl = "http://192.168.1.1/api/v1/module/search";
        Request request = new Request.Builder()
                .url(postUrl)
                .post(RequestBody.create(mediaType, info))
                .build();
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.newCall(request).enqueue(callback);
    }

    private static String getAddress(String url) {
        String finalResult = null;
        try {
            if (TextUtils.isEmpty(url)) {
                return null;
            }

            String cacheUrl = url;
            String result = null;
            if (url.startsWith("https://")) {
                String cache = cacheUrl.replace("https://", "").trim();
                result = cache.substring(0, cache.indexOf("/"));
            } else if (url.startsWith("http://")) {
                String cache = cacheUrl.replace("http://", "").trim();
                result = cache.substring(0, cache.indexOf("/"));
            }

            if (isMatch(ipRegex, result)) {
                return url;
            } else {
                InetAddress inetAddress = null;
                try {
                    inetAddress = InetAddress.getByName(result);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                String address = inetAddress.getHostAddress();
                if (address != null) {
                    if (isMatch(ipRegex, address)) {
                        finalResult = url.replace(result, address);
                    }
                } else {
                    Log.d("HttpUtil.getAddress", "address = null");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();

        }
        return finalResult;
    }

    private static final String ipRegex =
            "((?:(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d))))";

    private static boolean isMatch(String regex, String string) {
        return Pattern.matches(regex, string);
    }

    public static void resetDeviceStatusHost() {

    }

    private static String checkHost(String host){
        if (host.startsWith("http://")){
            return host.replace("http://", "https://");
        }else{
            return host;
        }
    }


    private static OkHttpClient sClient = null;
    private static String[] VERIFY_HOST_NAME_ARRAY = new String[]{};

    public static final HostnameVerifier createInsecureHostnameVerifier() {
        return (hostname, session) -> {
            if (TextUtils.isEmpty(hostname)) {
                return false;
            }
            return !Arrays.asList(VERIFY_HOST_NAME_ARRAY).contains(hostname);
        };
    }

    public synchronized static OkHttpClient getClient() {
        if (sClient == null) {

            HttpLogger httpLogger = new HttpLogger();
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor(httpLogger);
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);

            HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
            sClient = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(10, TimeUnit.SECONDS)
                    .sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager)
                    .hostnameVerifier(createInsecureHostnameVerifier())
                    .addNetworkInterceptor(logging)
                    .addInterceptor(new Interceptor() {
                        @Override
                        public Response intercept(Chain chain) throws IOException {
                            Request request = chain.request().newBuilder()
                                    .header("is_app", "1")
                                    .build();
                            return chain.proceed(request);
                        }
                    })
                    .connectionPool(new ConnectionPool(50, 10, TimeUnit.SECONDS))
                    .build();
        }

        return sClient;
    }
}
